{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 变换向量和图形"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 方法大全"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-11-2e8c4f1081b2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     10\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mdraw_model\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[1;33m*\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     11\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0mteapot\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[1;33m*\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 12\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0mrotate_teapot_x\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[1;33m*\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\rotate_teapot_x.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     34\u001b[0m \u001b[1;31m####################################################################\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     35\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 36\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpolygon_map\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mrotate_x_by\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mload_triangles\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "import pygame\n",
    "from pygame.locals import *\n",
    "from OpenGL.GL import *\n",
    "from OpenGL.GLU import *\n",
    "import matplotlib.cm\n",
    "import camera\n",
    "from vectors import *\n",
    "from math import *\n",
    "from transforms import *\n",
    "from draw_model import *\n",
    "from teapot import *\n",
    "from rotate_teapot_x import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def scale2(v):\n",
    "    # 将所有向量*标量2\n",
    "    return scale(2.0, v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'original_triangles' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-e5619c4f7035>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      4\u001b[0m a = [\n\u001b[0;32m      5\u001b[0m     \u001b[1;33m[\u001b[0m\u001b[0mscale2\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mv\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mv\u001b[0m \u001b[1;32min\u001b[0m \u001b[0me\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m     \u001b[1;32mfor\u001b[0m \u001b[0me\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m ]\n\u001b[0;32m      8\u001b[0m b = [\n",
      "\u001b[1;31mNameError\u001b[0m: name 'original_triangles' is not defined"
     ]
    }
   ],
   "source": [
    "def translatelleft(v):\n",
    "    # 将所有图形向左移动\n",
    "    return add((-1, 0, 0), v)\n",
    "a = [\n",
    "    [scale2(v) for v in e]\n",
    "    for e in original_triangles\n",
    "]\n",
    "b = [\n",
    "    [translatelleft(v) for v in w]\n",
    "    for w in a\n",
    "]\n",
    "draw_model(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compose(f1, f2):\n",
    "    # 函数式编程（将函数作为实参传入）\n",
    "    def new_function(input):\n",
    "        return f1(f2(input))\n",
    "    return new_function\n",
    "scale2_then_translatelleft = compose(translatelleft, scale2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'polygons' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-8-ed6e4fe1a91d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      4\u001b[0m         \u001b[1;32mfor\u001b[0m \u001b[0mtriangle\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mpolygons\u001b[0m \u001b[1;31m# 不同层拆包，要用两次列表推导式\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m     ]\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpolygons\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpolygon_map\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscale2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mload_triangles\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'polygons' is not defined"
     ]
    }
   ],
   "source": [
    "def polygon_map(transformation, polygons):\n",
    "    return [\n",
    "        [transformation(vertex) for vertex in triangle] \n",
    "        for triangle in polygons # 不同层拆包，要用两次列表推导式\n",
    "    ]\n",
    "\n",
    "draw_model(polygon_map(scale2, load_triangles()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def scale(scalar, vector):\n",
    "    # 向量乘以标量（方法2）\n",
    "    return tuple(scalar*i for i in vector)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'original_triangles' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-10-479cf33c139f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m a = [\n\u001b[0;32m      8\u001b[0m     \u001b[1;33m[\u001b[0m\u001b[0mscale_by\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m0.5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mb\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m     \u001b[1;32mfor\u001b[0m \u001b[0mb\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     10\u001b[0m ]\n\u001b[0;32m     11\u001b[0m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'original_triangles' is not defined"
     ]
    }
   ],
   "source": [
    "def scale_by(scalar):\n",
    "    # 缩放向量\n",
    "    def new_function(v):\n",
    "        return scale(scalar, v)\n",
    "    return new_function\n",
    "scale_by(2)((1, 2, 3))\n",
    "a = [\n",
    "    [scale_by(-0.5)(i) for i in b] \n",
    "    for b in original_triangles\n",
    "]\n",
    "draw_model(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'original_triangles' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-9-b5b6cef6139b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m a = [\n\u001b[0;32m      8\u001b[0m     \u001b[1;33m[\u001b[0m\u001b[0mtranslate_by\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mw\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m     \u001b[1;32mfor\u001b[0m \u001b[0mw\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     10\u001b[0m ]\n\u001b[0;32m     11\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moriginal_triangles\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'original_triangles' is not defined"
     ]
    }
   ],
   "source": [
    "def translate_by(v):\n",
    "    # 利用函数创造一个新的函数\n",
    "    def new_function(p):\n",
    "        return tuple(i+p for i in v)\n",
    "    return new_function\n",
    "translate_by((1, 2, 3))(9)\n",
    "a = [\n",
    "    [translate_by(i)(-1) for i in w]\n",
    "    for w in original_triangles\n",
    "]\n",
    "print(original_triangles)\n",
    "draw_model(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-65-7b2842ecb6ce>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      6\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mb\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      7\u001b[0m ]\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscales\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "def stretch_x(vector):\n",
    "    # 将x拉长为原来的四倍\n",
    "    return (4*vector[0], vector[1], vector[2])\n",
    "scales = [\n",
    "    [stretch_x(i) for i in b] \n",
    "    for b in original_triangles\n",
    "]\n",
    "draw_model(scales)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sin, cos,tan, pi\n",
    "def to_cartesian(polar_vector):\n",
    "    # 将极坐标转换为笛卡尔坐标a\n",
    "    length, angle = polar_vector[0], polar_vector[1]\n",
    "    return (length*cos(angle), length*sin(angle))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.605551275463989, 2.158798930342464)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from math import asin,acos,atan2,sqrt\n",
    "def to_polar(vector):\n",
    "    # 将笛卡尔坐标转换为极坐标\n",
    "    x, y = vector[0], vector[1]\n",
    "    angle = atan2(y,x)\n",
    "    return (length(vector), angle)\n",
    "to_polar((-2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [],
   "source": [
    "def route_y_1(angle, v):\n",
    "    r, i = to_polar(v)\n",
    "    return to_cartesian((r, i+angle))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-2.0980762113533156, 3, 2.3660254037844393)"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def route_y_2(angle, t):\n",
    "    new_a1, new_a3 = route_y_1(angle, (t[0], t[2]))\n",
    "    return new_a1, t[2], new_a3\n",
    "route_y_2(pi/3, (1, 2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-69-523a9065bde0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mv\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m ]\n\u001b[1;32m----> 9\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "def route_y_3(angle):\n",
    "    def new_function(v):\n",
    "        return route_y_2(angle, v)\n",
    "    return new_function\n",
    "a = [\n",
    "    [route_y_3(pi)((i)) for i in v]\n",
    "    for v in original_triangles\n",
    "]\n",
    "draw_model(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def translate_by_1(p, v):\n",
    "    return tuple(p+i for i in v)\n",
    "translate_by_1(3, (1, 2, 3, 4, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-70-611ababc2812>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mc\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m ]\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "def zz(i, v):\n",
    "    return (v[0], v[1], v[2]-i)\n",
    "a = [\n",
    "    [zz(20, v) for v in c]\n",
    "    for c in original_triangles\n",
    "]\n",
    "draw_model(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stretch_y(l, v):\n",
    "    return (v[0]+v[1]*l, v[1], v[2])\n",
    "def strech_y_2(l):\n",
    "    def new_function(v):\n",
    "        return stretch_y(l, v)\n",
    "    return new_function\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 5, 6)"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def add_1(p, v):\n",
    "    return tuple(p+i for i in v)\n",
    "def translate_by_2(p):\n",
    "    def new_function(v):\n",
    "        return add_1(p, v)\n",
    "    return new_function\n",
    "translate_by_2(3)((1, 2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(27, 7, 8)"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def compose_1(*args):    # 应该是利用同名形参建立函数参数之间的联系\n",
    "    def new_function(input):    \n",
    "        state = input\n",
    "        for f in reversed(args): # 在函数内的for循环中，若循环到了return句，就会直接退出循环并返回值\n",
    "            state = f(state)     # 第一次循环的结果作为了第二次循环的实参并传入\n",
    "        return state\n",
    "    return new_function\n",
    "\n",
    "i = compose_1(strech_y_2(3), translate_by_2(5))\n",
    "i((1, 2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello, python'"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def prepend(string):\n",
    "    def new_function(input):\n",
    "        return string + input\n",
    "    return new_function\n",
    "i = compose_1(prepend('Hello,'), prepend(' py'), prepend('t'))\n",
    "i('hon')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-74-bbc0c46ea337>, line 8)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-74-bbc0c46ea337>\"\u001b[1;36m, line \u001b[1;32m8\u001b[0m\n\u001b[1;33m    return def new_function_2(y):\u001b[0m\n\u001b[1;37m             ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "def a(x, y):\n",
    "    return (x+3, y+5)\n",
    "print(a(3, 5))\n",
    "\n",
    "def curry_2(f):\n",
    "    def new_function_1(x):\n",
    "        b = x\n",
    "        return def new_function_2(y):\n",
    "                return a(b, y)\n",
    "    return new_function_1\n",
    "curry_2(a)(3)(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "def rr(x, y):\n",
    "    return x + y\n",
    "def ac(x):\n",
    "    def new_function(y):\n",
    "        return rr(x, y) # 通过同名形参建立联系\n",
    "    return new_function\n",
    "print(rr(1, 2))\n",
    "print(ac(1)(2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 2, 3)\n",
      "(2, 2, 3)\n"
     ]
    }
   ],
   "source": [
    "def stretch_x(scalar, vector):\n",
    "    return tuple([scalar*vector[0]] + [i for i in vector[1:]])\n",
    "print(stretch_x(2, (1, 2, 3)))\n",
    "\n",
    "def stretch_x_by(scalar):\n",
    "    def new_function(vector):\n",
    "        return stretch_x(scalar, vector)\n",
    "    return new_function\n",
    "print(stretch_x_by(2)((1, 2, 3)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-80-d92f30e0b7f6>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m     10\u001b[0m     \u001b[1;32mfor\u001b[0m \u001b[0mb\u001b[0m \u001b[1;32min\u001b[0m \u001b[0moriginal_triangles\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     11\u001b[0m ]\n\u001b[1;32m---> 12\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ma\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "Ae1 = (1, 1, 1)\n",
    "Ae2 = (1, 0, -1)\n",
    "Ae3 = (0, 1, 1)\n",
    "\n",
    "def apply_A(v):\n",
    "    return sum([v[0]*Ae1[0], v[1]*Ae2[0], v[2]*Ae3[0]]), sum([v[0]*Ae1[1], v[1]*Ae2[1], v[2]*Ae3[1]]), sum([v[0]*Ae1[2], v[1]*Ae2[2], v[2]*Ae3[2]])\n",
    "apply_A((-1, 2, 2))\n",
    "a = [\n",
    "    [apply_A(i) for i in b]\n",
    "    for b in original_triangles\n",
    "]\n",
    "draw_model(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'tuple' object has no attribute 'remove'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-3-051ca5472717>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      7\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 9\u001b[1;33m \u001b[0mlinear_combination\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     10\u001b[0m     \u001b[1;31m# w = []\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     11\u001b[0m     \u001b[1;31m#w.append([sum([c[i][r] for i in range(0, len(c)) for r in c])])\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-3-051ca5472717>\u001b[0m in \u001b[0;36mlinear_combination\u001b[1;34m(scalars, *vectors)\u001b[0m\n\u001b[0;32m      4\u001b[0m         \u001b[0mc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mscalars\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mi\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mvectors\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      5\u001b[0m         \u001b[0mscalars\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscalars\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m         \u001b[0mvectors\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mremove\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mvectors\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      7\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      8\u001b[0m     \u001b[1;32mreturn\u001b[0m \u001b[0mc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'tuple' object has no attribute 'remove'"
     ]
    }
   ],
   "source": [
    "def linear_combination(scalars, *vectors):\n",
    "    c = []\n",
    "    while len(scalars)>0:\n",
    "        c.append([scalars[0]*i for i in vectors[0]])\n",
    "        scalars.remove(scalars[0])\n",
    "        vectors.remove(vectors[0])\n",
    "   \n",
    "    return c\n",
    "linear_combination([1, 2, 3], [[[1, 2, 3], [1, 2, 3]]])\n",
    "    # w = []\n",
    "    #w.append([sum([c[i][r] for i in range(0, len(c)) for r in c])])\n",
    "    \n",
    "    \n",
    "        \n",
    "c = [[1, 2, 3], [2, 2, 3]]\n",
    "print(c[1][0])\n",
    "print(len(c))\n",
    "print(sum([i for i in range(1, 10)]))\n",
    "print([sum([c[i][0] for i in range(0, len(c))])])\n",
    "#w = [sum([c[i][0] for i in range(0, len(c))])\n",
    "#print(w)\n",
    "#print(sum(((([1, 2]))))) # []只能有一个\n",
    "#print(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 2, 3)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def linear_combination(scalars, *vectors):\n",
    "    c, e, f = [scalars[0]*i for i in vectors[0]], [scalars[1]*i for i in vectors[1]], [scalars[2]*i for i in vectors[2]]\n",
    "    return tuple([sum([c[0], e[0], f[0]]), sum([c[1], e[1], f[1]]), sum([c[2], e[2], f[2]])])\n",
    "linear_combination([1, 2, 3], (1, 0, 0), (0, 1, 0), (0, 0, 1))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((1, 0, 0), (0, 2, 0), (0, 0, 3))"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def transform_standard_basis(transform):\n",
    "    return (tuple([transform[0]*i for i in (1, 0, 0)]), tuple([transform[1]*i for i in (0, 1, 0)]), tuple([transform[2]*i for i in (0, 0, 1)]))\n",
    "transform_standard_basis((1, 2, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "original_triangles = load_triangles()\n",
    "scaled_triangles = [\n",
    "    [scale2(vertex) for vertex in triangle]\n",
    "    for triangle in original_triangles\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'quit' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-79-d4b5fdb43241>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdraw_model\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mscaled_triangles\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\draw_model.py\u001b[0m in \u001b[0;36mdraw_model\u001b[1;34m(faces, color_map, light, glRotatefArgs, get_matrix)\u001b[0m\n\u001b[0;32m     51\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mevent\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtype\u001b[0m \u001b[1;33m==\u001b[0m \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQUIT\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     52\u001b[0m                 \u001b[0mpygame\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 53\u001b[1;33m                 \u001b[0mquit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     54\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     55\u001b[0m         \u001b[0mglClear\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mGL_COLOR_BUFFER_BIT\u001b[0m\u001b[1;33m|\u001b[0m\u001b[0mGL_DEPTH_BUFFER_BIT\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mNameError\u001b[0m: name 'quit' is not defined"
     ]
    }
   ],
   "source": [
    "draw_model(scaled_triangles)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaled_translated_triangles = [\n",
    "    [translatelleft(scale2(vertex)) for vertex in triangle]\n",
    "    for triangle in original_triangles\n",
    "]\n",
    "draw_model(scaled_translated_triangles)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 组合向量变换"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
